package com.jeesite.modules.service;

import com.jeesite.common.entity.Page;
import com.jeesite.common.service.CrudService;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.modules.dao.UserDao;
import com.jeesite.modules.auth.entity.AuthUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

/**
 * 用户Service
 * @author JeeSite
 * @version 2024-01-01
 */
@Service("authUserService")
@Transactional(readOnly = true)
public class UserService {
    
    @Autowired
    private UserDao dao;
    
    /**
     * 获取单条数据
     * @param user 用户对象
     * @return 用户信息
     */
    public AuthUser get(AuthUser user) {
        return dao.findById(Long.parseLong(user.getId()));
    }
    
    /**
     * 查询分页数据
     * @param user 用户对象
     * @return 分页数据
     */
    public Page<AuthUser> findPage(AuthUser user) {
        // 简化实现，实际项目中需要完整的分页逻辑
        Page<AuthUser> page = new Page<>();
        return page;
    }
    
    /**
     * 根据用户名查询用户
     * @param username 用户名
     * @return 用户信息
     */
    public AuthUser findByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        return dao.findByUsername(username);
    }
    
    /**
     * 根据ID查询用户
     * @param id 用户ID
     * @return 用户信息
     */
    public AuthUser findById(Long id) {
        if (id == null) {
            return null;
        }
        return dao.findById(id);
    }
    
    /**
     * 根据邮箱查询用户
     * @param email 邮箱
     * @return 用户信息
     */
    public AuthUser getByEmail(String email) {
        if (StringUtils.isBlank(email)) {
            return null;
        }
        return dao.getByEmail(email);
    }
    
    /**
     * 根据手机号查询用户
     * @param mobile 手机号
     * @return 用户信息
     */
    public AuthUser getByMobile(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return null;
        }
        return dao.getByMobile(mobile);
    }
    
    /**
     * 检查登录账号是否存在
     * @param loginCode 登录账号
     * @return 存在返回true，否则返回false
     */
    public boolean existsByLoginCode(String loginCode) {
        if (StringUtils.isBlank(loginCode)) {
            return false;
        }
        return dao.existsByLoginCode(loginCode);
    }
    
    /**
     * 检查邮箱是否存在
     * @param email 邮箱
     * @return 存在返回true，否则返回false
     */
    public boolean existsByEmail(String email) {
        if (StringUtils.isBlank(email)) {
            return false;
        }
        return dao.existsByEmail(email);
    }
    
    /**
     * 检查手机号是否存在
     * @param mobile 手机号
     * @return 存在返回true，否则返回false
     */
    public boolean existsByMobile(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return false;
        }
        return dao.existsByMobile(mobile);
    }
    
    /**
     * 检查用户名是否存在
     * @param username 用户名
     * @return 存在返回true，否则返回false
     */
    public boolean existsByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return false;
        }
        return dao.existsByUsername(username);
    }
    
    /**
     * 保存数据（插入或更新）
     * @param user 用户对象
     */
    @Transactional(readOnly = false)
    public void save(AuthUser user) {
        // 如果是新增用户
        if (user.getId() == null || user.getId().isEmpty()) {
            // 设置创建时间和更新时间
            java.util.Date now = new java.util.Date();
            user.setCreatedAt(now);
            user.setUpdatedAt(now);
            // 设置默认状态
            if (user.getStatus() == null) {
                user.setStatus("ACTIVE");
            }
            // 设置默认角色
            if (user.getRole() == null) {
                user.setRole("USER");
            }
            dao.save(user);
        } else {
            // 更新时设置更新时间
            user.setUpdatedAt(new java.util.Date());
            dao.update(user);
        }
    }
    
    /**
     * 更新用户
     * @param user 用户对象
     */
    @Transactional(readOnly = false)
    public void update(AuthUser user) {
        // 设置更新时间
        user.setUpdatedAt(new java.util.Date());
        // 调用自定义的updateUser方法，避免与CrudDao的update冲突
        dao.updateUser(user);
    }
    
    /**
     * 删除用户
     * @param id 用户ID
     */
    @Transactional(readOnly = false)
    public void delete(Long id) {
        dao.delete(id);
    }
    
    /**
     * 用户注册
     * @param loginCode 登录账号
     * @param password 密码
     * @param userName 用户姓名
     * @param email 邮箱
     * @return 注册结果
     */
    @Transactional(readOnly = false)
    public AuthUser register(String loginCode, String password, String userName, String email) {
        // 检查登录账号是否已存在
        if (existsByUsername(loginCode)) {
            throw new RuntimeException("登录账号已存在");
        }
        
        // 检查邮箱是否已存在（如果提供了邮箱）
        if (StringUtils.isNotBlank(email) && existsByEmail(email)) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 创建新用户
        AuthUser user = new AuthUser();
        user.setUsername(loginCode);
        user.setPassword(hashPassword(password));
        user.setNickname(userName);
        user.setStatus("ACTIVE");
        user.setRole("USER");
        
        // 设置默认头像
        user.setAvatar("https://trae-api-us.mchost.guru/api/ide/v1/text_to_image?prompt=default%20user%20avatar%20icon%20modern%20style&image_size=square");
        
        // 保存用户
        this.save(user);
        
        return user;
    }
    
    /**
     * 用户登录验证
     * @param loginCode 登录账号
     * @param password 密码
     * @param loginIp 登录IP
     * @return 用户信息，验证失败返回null
     */
    @Transactional(readOnly = false)
    public AuthUser login(String loginCode, String password, String loginIp) {
        // 根据登录账号查询用户
        AuthUser user = findByUsername(loginCode);
        if (user == null) {
            return null;
        }
        
        // 验证密码
        String hashedPassword = hashPassword(password);
        if (!user.getPassword().equals(hashedPassword)) {
            return null;
        }
        
        // 更新最后登录信息
        updateLastLoginInfo(user.getId(), loginIp, new Date());
        
        return user;
    }
    
    /**
     * 更新用户最后登录信息
     * @param userCode 用户编码
     * @param lastLoginIp 最后登录IP
     * @param lastLoginDate 最后登录时间
     */
    @Transactional(readOnly = false)
    public void updateLastLoginInfo(String userCode, String lastLoginIp, Date lastLoginDate) {
        dao.updateLastLoginInfo(userCode, lastLoginIp, lastLoginDate);
    }
    
    /**
     * 更新用户密码
     * @param userCode 用户编码
     * @param newPassword 新密码
     */
    @Transactional(readOnly = false)
    public void updatePassword(String userCode, String newPassword) {
        String hashedPassword = hashPassword(newPassword);
        dao.updatePassword(userCode, hashedPassword, new Date());
    }
    
    /**
     * 密码哈希
     * @param password 原始密码
     * @return 哈希后的密码
     */
    public static String hashPassword(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(password.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("密码加密失败", e);
        }
    }
    
    /**
     * 验证密码
     * @param rawPassword 原始密码
     * @param hashedPassword 哈希密码
     * @return 验证结果
     */
    public static boolean verifyPassword(String rawPassword, String hashedPassword) {
        return hashPassword(rawPassword).equals(hashedPassword);
    }
}